using System;
using System.Linq;
using System.Reflection;

namespace devtm.Aop.Linq
{
	public static class MethodInfoExtension
	{


        public static MethodInfo[] SelectOverridableMethods(this MethodInfo[] methods)
        {
            return methods.Where(m => m.IsVirtual && !m.IsFinal).ToArray();
        }


        public static MethodInfo[] SelectPropertyGetters(this MethodInfo[] methods)
        {
			return methods.Where(m => m.Name.StartsWith("get_", StringComparison.OrdinalIgnoreCase)).ToArray();
        }


        public static MethodInfo[] SelectPropertySetters(this MethodInfo[] methods) 
        {
            return methods.Where(m => m.Name.StartsWith("set_", StringComparison.OrdinalIgnoreCase)).ToArray();
        }

		public static Type[] GetMethodParameterTypes(this MethodInfo method)
		{
			return (from t in method.GetParameters()
					select t.ParameterType).ToArray();
		}


        public static MethodSign ExtractMethodSignature(this MethodInfo info)
        {
            return new MethodSign(info);
        }


        public static MethodInfo[] GetMethodsToIntercept(this Type type)
        {
            return type.IsInterface ?
                type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public)
                : type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public)
				.SelectOverridableMethods();
		}


	}
}
